<?php
/**
 * Created by PhpStorm.
 * User: 9ey
 * Date: 2019/5/19
 * Time: 11:58
 */

namespace App\Repositories\System;

use App\Models\System\File;
use App\Utils\AliOssClient;
use App\Utils\Output;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;

class FileRepository
{
    //上传图片格式
    public $imageAllowFiles = [
        '.png',
        '.jpg',
        '.jpeg',
        '.gif',
        '.bmp',
    ];

    //上传视频格式
    public $videoAllowFiles = [
        '.flv',
        '.swf',
        '.mkv',
        '.avi',
        '.rm',
        '.rmvb',
        '.mpeg',
        '.mpg',
        '.ogg',
        '.ogv',
        '.mov',
        '.wmv',
        '.mp4',
        '.webm',
        '.mp3',
        '.wav',
        '.mid',
    ];

    //上传文件格式
    public $fileAllowFiles = [
        '.png',
        '.jpg',
        '.jpeg',
        '.gif',
        '.bmp',
        '.flv',
        '.swf',
        '.mkv',
        '.avi',
        '.rm',
        '.rmvb',
        '.mpeg',
        '.mpg',
        '.ogg',
        '.ogv',
        '.mov',
        '.wmv',
        '.mp4',
        '.webm',
        '.mp3',
        '.wav',
        '.mid',
        '.rar',
        '.zip',
        '.tar',
        '.gz',
        '.7z',
        '.bz2',
        '.cab',
        '.iso',
        '.doc',
        '.docx',
        '.xls',
        '.xlsx',
        '.ppt',
        '.pptx',
        '.pdf',
        '.txt',
        '.md',
        '.xml',
        '.ipa',
        '.apk',
        '.plist',
        '.exe',
    ];

    /**
     * 上传文件大小
     * @var int
     */
    protected $maxFileSize;

    /**
     * 储存类型 (1-服务器 2-OSS)
     * @var int|mixed
     */
    protected $saveType;

    /**
     * 储存地点
     * @var string
     */
    protected $destination = null;

    public function __construct($type = 1, $size = 100 * 1024 * 1024)
    {
        $this->saveType = $type;
        $this->destination = public_path('uploads');
        $this->maxFileSize = $size;
    }

    /**
     * 上传图片
     * @param $files
     * @return Output
     */
    public function image($files, $module)
    {
        return $this->parseFile($files, $this->imageAllowFiles, $module, 2);
    }

    /**
     * 上传视频
     * @param $files
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function video($files, $module)
    {
        return $this->parseFile($files, $this->videoAllowFiles, $module, 2);
    }

    /**
     * 上传文件
     * @param $files
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function file($files, $module)
    {
        return $this->parseFile($files, $this->fileAllowFiles, $module);
    }

    /**
     * 上传核心
     * @param UploadedFile[] $files
     * @param $types
     * @return Output
     */
    private function parseFile($files, $types, $module, $type = 1)
    {
        if (empty($files) || empty(Arr::first($files))) {
            return Output::fail('请选择上传文件');
        }
        try {
            $data = [];
            foreach ($files as $file) {
                $mimeType = $file->getClientMimeType();
                $mimeTypeArray = @explode('/', $mimeType);
                $nameArray = @explode('.', $file->getClientOriginalName());
                $suffix = strtolower(end($nameArray));

                $mimeTypeTmp = strtolower($mimeTypeArray[count($mimeTypeArray) - 1]);

                $fileSize = $file->getSize();

                if (!is_uploaded_file($file->getRealPath())) {
                    return Output::fail('上传文件不存在');
                }

                if ($fileSize > $this->maxFileSize) {
                    return Output::fail('文件大小超出限制' . round(($this->maxFileSize / 1024) / 1024, 2) . 'MB');
                }

                if (Arr::first($mimeTypeArray) == 'image' && $suffix == 'blob') {
                    $suffix = strtolower($mimeTypeTmp);
                }

                if (!in_array('.' . $suffix, $types)) {
                    return Output::fail('文件类型错误');
                }
                $inFile = new File();
                $_name = $file->getClientOriginalName();
                $inFile->name = strlen($_name) > 50 ? substr($_name, 0, 50) : $_name;
                $inFile->module = $module;
                $inFile->type = $type;
                $inFile->md5 = "";
//                $inFile->md5 = md5_file($file->getPath());
//                $path = 'public/' . date('YmdHis') . rand(10000, 99999) . '.' . $file->getClientOriginalExtension();
//                AliOssClient::uploadFile($file->getRealPath(), $path);
//                $inFile->path = $path;

                $fileName = uniqid() . '.' . $file->getClientOriginalExtension();
                $dir = date('/ymd') . DIRECTORY_SEPARATOR;
                $inFile->path = $dir . $fileName;
                $dirPath = storage_path('app' . DIRECTORY_SEPARATOR . 'public') . $dir;
                if (!is_dir($dirPath)) {
                    \Illuminate\Support\Facades\File::makeDirectory($dirPath, 0777, true);
                }
                $file->move($dirPath, $fileName);
                $inFile->md5 = md5_file(storage_path('app' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . $inFile->path));
                $inFile->save();
                $data[] = [
                    'id' => $inFile->id,
                    'url' => '/storage' . str_replace('\\', '/', $inFile->path)
                ];
            }
            return Output::data($data);
        } catch (\Exception $exception) {
            Log::info($exception->getMessage() . "\r\n" . $exception->getTraceAsString());
            return Output::fail($exception->getMessage());
        }
    }
}
